package com.frank.loadinglibrary.special.eatbean;

import com.frank.loadinglibrary.common.BaseLoadingComponent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * @author SUQI
 * @date 2021/5/6
 * @description
 **/
public class EatBeansComponent extends BaseLoadingComponent implements Component.DrawTask {

    public final static int LINE = 1;
    public final static int CIRCLE = 2;

    private int viewType = CIRCLE;
    private Paint mPaint;
    private Paint mPaintEye;
    private float mWidth;
    private float mHigh;
    private float mPadding = 5f;
    private float eatErWidth = 40f;
    private float eatErPositionX = 0f;
    private float eatErPositionY = 0f;
    int eatSpeed = 5;
    private float beansWidth = 10f;
    private int beansCount = 10;
    private float mAngle = 30;
    private float eatErStartAngle = mAngle;
    private float eatErEndAngle = 360 - 2 * eatErStartAngle;
    private AnimatorValue animatorValue;
    private int animatorTime = 10000;
    private float radius;
    private float moveAngle;
    private Color beansColor = Color.WHITE;
    private Color eatErColor = Color.BLACK;



    public EatBeansComponent(Context context) {
        this(context, null);
    }

    public EatBeansComponent(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public EatBeansComponent(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        InitPaint();
    }

    private void InitPaint() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setColor(eatErColor);

        mPaintEye = new Paint();
        mPaintEye.setAntiAlias(true);
        mPaintEye.setStyle(Paint.Style.FILL_STYLE);
        mPaintEye.setColor(beansColor);
        addDrawTask(this);
        startAnimators();
    }

    @Override
    protected void stopAnimators() {
        if (null != animatorValue) {
            animatorValue.cancel();
            animatorValue.end();
        }
    }

    @Override
    protected void startAnimators() {
        animatorValue = new AnimatorValue();
        animatorValue.setLoopedCount(Animator.INFINITE);
        animatorValue.setDuration(animatorTime);
        animatorValue.setValueUpdateListener((animatorValue, v) -> {
            if (viewType == LINE) {
                eatErPositionX = (mWidth - 2 * mPadding - eatErWidth) * v;
                eatErStartAngle = mAngle * (1 - (v * eatSpeed - (int) (v * eatSpeed)));
                eatErEndAngle = 360 - eatErStartAngle * 2;
            } else {
                moveAngle = 360 * v;
                eatErPositionY = (float) (mHigh / 2 - Math.sin(Math.toRadians(360 * v)) * radius);
                eatErPositionX = (float) (mWidth / 2 - Math.cos(Math.toRadians(360 * v)) * radius);
                float rate = (float) Math.abs(Math.sin(Math.toRadians(moveAngle * 4)));
                eatErStartAngle = 300 + moveAngle - mAngle * rate;
                eatErEndAngle = 300 +  2 * mAngle * rate;
            }
            invalidate();
        });
        animatorValue.start();
    }

    @Override
    protected void releaseSource() {

    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        mWidth = getWidth();
        mHigh = getHeight();
        radius = Math.min(mWidth, mHigh) / 2 - 60;
        mPaint.setColor(eatErColor);
        mPaintEye.setColor(beansColor);

        if (viewType == LINE) {
            float eatRightX = mPadding + eatErWidth + eatErPositionX;
            RectFloat rectF = new RectFloat(mPadding + eatErPositionX, mHigh / 2 - eatErWidth / 2, eatRightX, mHigh / 2 + eatErWidth / 2);
            canvas.drawArc(rectF, new Arc(eatErStartAngle, eatErEndAngle, true), mPaint);
            canvas.drawCircle(mPadding + eatErPositionX + eatErWidth / 2, mHigh / 2 - eatErWidth / 4, beansWidth / 2, mPaintEye);
            int beansCount = (int) ((mWidth - mPadding * 2 - eatErWidth) / beansWidth / 2);
            for (int i = 0; i < beansCount; i++) {
                float x = beansCount * i + beansWidth / 2 + mPadding + eatErWidth;
                if (x > eatRightX) {
                    canvas.drawCircle(x, mHigh / 2, beansWidth / 2, mPaint);
                }
            }
        } else {
            RectFloat rectF = new RectFloat(eatErPositionX - eatErWidth / 2, eatErPositionY - eatErWidth / 2, eatErPositionX + eatErWidth / 2, eatErPositionY + eatErWidth / 2);
            canvas.drawArc(rectF, new Arc(eatErStartAngle, eatErEndAngle, true), mPaint);
            canvas.drawCircle((float) (mWidth / 2 - Math.cos(Math.toRadians(moveAngle + 5)) * (radius + eatErWidth / 4)),
                    (float) (mHigh / 2 - Math.sin(Math.toRadians(moveAngle + 5)) * (radius + eatErWidth / 4)), beansWidth / 2, mPaintEye);
            int angleAverage = 360 / beansCount;
            for (int i = 0; i < beansCount; i++) {
                if (i * angleAverage >= moveAngle) {
                    canvas.rotate(-angleAverage, mWidth / 2, mHigh / 2);
                    canvas.drawCircle((float) (mWidth / 2 - Math.cos(Math.toRadians(0)) * radius), mHigh / 2, beansWidth / 2, mPaintEye);
                }
            }
        }
    }

    public EatBeansComponent setViewType(int viewType) {
        this.viewType = viewType;
        return this;
    }

    public EatBeansComponent setBeansWidth(float beansWidth) {
        this.beansWidth = beansWidth;
        return this;
    }

    public EatBeansComponent setEatErStartAngle(float eatErStartAngle) {
        this.eatErStartAngle = eatErStartAngle;
        return this;
    }

    public EatBeansComponent setBeansColor(Color beansColor) {
        this.beansColor = beansColor;
        return this;
    }

    public EatBeansComponent setEatErColor(Color eatErColor) {
        this.eatErColor = eatErColor;
        return this;
    }

    public EatBeansComponent setBeansCount(int beansCount) {
        this.beansCount = beansCount;
        return this;
    }

    public EatBeansComponent setEatErWidth(float eatErWidth) {
        this.eatErWidth = eatErWidth;
        return this;
    }
}
